package com.fancy.music.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fancy.common.dto.ArtistBasicInfo;
import com.fancy.common.dto.PageResult;
import com.fancy.music.dto.ArtistDetailDTO;
import com.fancy.music.entity.Artist;
import com.fancy.music.entity.Album;
import com.fancy.music.entity.Song;
import com.fancy.music.mapper.ArtistMapper;
import com.fancy.music.mapper.AlbumMapper;
import com.fancy.music.mapper.SongMapper;
import com.fancy.music.service.ArtistService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ArtistServiceImpl implements ArtistService {

    private final ArtistMapper artistMapper;
    private final AlbumMapper albumMapper;
    private final SongMapper songMapper;

    @Override
    public Artist getArtistDetail(Long artistId) {
        return artistMapper.selectById(artistId);
    }

    @Override
    public ArtistDetailDTO getArtistDetailWithInfo(Long artistId) {
        Artist artist = artistMapper.selectById(artistId);
        if (artist == null) {
            return null;
        }
        return convertToArtistDetailDTO(artist);
    }

    @Override
    public PageResult<Artist> searchArtists(String keyword, String genre, String country, Integer gender, int page, int size) {
        Page<Artist> pageRequest = new Page<>(page, size);
        QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();

        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(wrapper ->
                wrapper.like("artist_name", keyword)
                       .or()
                       .like("artist_name_en", keyword)
            );
        }

        if (StringUtils.hasText(genre)) {
            queryWrapper.eq("genre", genre);
        }

        if (StringUtils.hasText(country)) {
            queryWrapper.eq("country", country);
        }

        if (gender != null) {
            queryWrapper.eq("gender", gender);
        }

        queryWrapper.eq("status", 1)
                   .orderByDesc("create_time");

        Page<Artist> pageResult = artistMapper.selectPage(pageRequest, queryWrapper);
        return new PageResult<>(pageResult.getRecords(), pageResult.getTotal(),
                               pageResult.getSize(), pageResult.getCurrent());
    }

    @Override
    public PageResult<ArtistDetailDTO> searchArtistsWithDetails(String keyword, String genre, String country, Integer gender, int page, int size) {
        PageResult<Artist> artistPage = searchArtists(keyword, genre, country, gender, page, size);
        List<ArtistDetailDTO> detailDTOs = artistPage.getRecords().stream()
                .map(this::convertToArtistDetailDTO)
                .collect(Collectors.toList());
        return new PageResult<>(detailDTOs, artistPage.getTotal(),
                               artistPage.getSize(), artistPage.getCurrent());
    }

    @Override
    public List<Artist> getHotArtists(Integer limit) {
        return artistMapper.selectHotArtists(limit != null ? limit : 10);
    }

    @Override
    public List<ArtistDetailDTO> getHotArtistsWithDetails(Integer limit) {
        List<Artist> artists = artistMapper.selectHotArtists(limit != null ? limit : 10);
        return artists.stream()
                .map(this::convertToArtistDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<Artist> getArtistsByGenre(String genre, Integer limit) {
        return artistMapper.selectByGenre(genre);
    }

    @Override
    public List<ArtistDetailDTO> getArtistsByGenreWithDetails(String genre, Integer limit) {
        List<Artist> artists = artistMapper.selectByGenre(genre);
        return artists.stream()
                .map(this::convertToArtistDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<Artist> getArtistsByCountry(String country, Integer limit) {
        return artistMapper.selectByCountry(country);
    }

    @Override
    public List<ArtistDetailDTO> getArtistsByCountryWithDetails(String country, Integer limit) {
        List<Artist> artists = artistMapper.selectByCountry(country);
        return artists.stream()
                .map(this::convertToArtistDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public ArtistBasicInfo getArtistBasicInfo(Long artistId) {
        Artist artist = artistMapper.selectById(artistId);
        if (artist == null) {
            return null;
        }

        ArtistBasicInfo info = new ArtistBasicInfo();
        info.setArtistId(artist.getArtistId());
        info.setArtistName(artist.getArtistName());
        info.setArtistNameEn(artist.getArtistNameEn());
        info.setGender(artist.getGender());
        info.setCountry(artist.getCountry());
        info.setAvatarUrl(artist.getAvatarUrl());
        info.setIntroduction(artist.getIntroduction());
        info.setGenre(artist.getGenre());

        return info;
    }

    @Override
    public List<ArtistBasicInfo> getArtistBasicInfoBatch(List<Long> artistIds) {
        if (artistIds == null || artistIds.isEmpty()) {
            return Collections.emptyList();
        }

        List<Artist> artists = artistMapper.selectBatchIds(artistIds);
        return artists.stream()
                .map(this::convertToBasicInfo)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Long createArtist(Artist artist) {
        try {
            artist.setCreateTime(new Date());
            artist.setUpdateTime(new Date());
            artist.setStatus(1); // 默认启用

            int result = artistMapper.insert(artist);
            if (result > 0) {
                return artist.getArtistId();
            }
            return null;
        } catch (Exception e) {
            log.error("创建歌手失败", e);
            return null;
        }
    }

    @Override
    @Transactional
    public boolean updateArtist(Artist artist) {
        try {
            artist.setUpdateTime(new Date());
            return artistMapper.updateById(artist) > 0;
        } catch (Exception e) {
            log.error("更新歌手失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean deleteArtist(Long artistId) {
        try {
            int result = artistMapper.deleteById(artistId);
            return result > 0;
        } catch (Exception e) {
            log.error("删除歌手失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean toggleArtistStatus(Long artistId, Integer status) {
        try {
            Artist artist = new Artist();
            artist.setArtistId(artistId);
            artist.setStatus(status);
            artist.setUpdateTime(new Date());

            return artistMapper.updateById(artist) > 0;
        } catch (Exception e) {
            log.error("切换歌手状态失败", e);
            return false;
        }
    }

    @Override
    public List<Artist> getNewArtists(Integer limit) {
        QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1)
                   .orderByDesc("debut_date")
                   .last("LIMIT " + (limit != null ? limit : 10));

        return artistMapper.selectList(queryWrapper);
    }

    @Override
    public List<ArtistDetailDTO> getNewArtistsWithDetails(Integer limit) {
        List<Artist> artists = getNewArtists(limit);
        return artists.stream()
                .map(this::convertToArtistDetailDTO)
                .collect(Collectors.toList());
    }

    private ArtistBasicInfo convertToBasicInfo(Artist artist) {
        ArtistBasicInfo info = new ArtistBasicInfo();
        info.setArtistId(artist.getArtistId());
        info.setArtistName(artist.getArtistName());
        info.setArtistNameEn(artist.getArtistNameEn());
        info.setGender(artist.getGender());
        info.setCountry(artist.getCountry());
        info.setAvatarUrl(artist.getAvatarUrl());
        info.setIntroduction(artist.getIntroduction());
        info.setGenre(artist.getGenre());
        return info;
    }

    /**
     * 将Artist实体转换为ArtistDetailDTO，包含统计信息
     */
    private ArtistDetailDTO convertToArtistDetailDTO(Artist artist) {
        ArtistDetailDTO dto = new ArtistDetailDTO();
        dto.setArtistId(artist.getArtistId());
        dto.setArtistName(artist.getArtistName());
        dto.setArtistNameEn(artist.getArtistNameEn());
        dto.setGender(artist.getGender());
        dto.setCountry(artist.getCountry());
        dto.setBirthDate(artist.getBirthDate());
        dto.setAvatarUrl(artist.getAvatarUrl());
        dto.setCoverUrl(artist.getCoverUrl());
        dto.setIntroduction(artist.getIntroduction());
        dto.setDebutDate(artist.getDebutDate());
        dto.setGenre(artist.getGenre());
        dto.setStatus(artist.getStatus());
        dto.setCreateTime(artist.getCreateTime());
        dto.setUpdateTime(artist.getUpdateTime());

        // 获取统计信息
        try {
            // 获取歌曲数量
            QueryWrapper<Song> songQuery = new QueryWrapper<>();
            songQuery.eq("artist_id", artist.getArtistId()).eq("status", 1);
            Long songCount = songMapper.selectCount(songQuery);
            dto.setSongCount(songCount.intValue());

            // 获取专辑数量
            QueryWrapper<Album> albumQuery = new QueryWrapper<>();
            albumQuery.eq("artist_id", artist.getArtistId()).eq("status", 1);
            Long albumCount = albumMapper.selectCount(albumQuery);
            dto.setAlbumCount(albumCount.intValue());

            // 粉丝数量暂时设为0，实际应用中应该从社交服务获取
            dto.setFollowerCount(0L);
        } catch (Exception e) {
            log.warn("获取歌手统计信息失败, artistId: {}", artist.getArtistId(), e);
            dto.setSongCount(0);
            dto.setAlbumCount(0);
            dto.setFollowerCount(0L);
        }

        return dto;
    }

    @Override
    public List<String> getAllArtistGenres() {
        try {
            QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1)
                       .isNotNull("genre")
                       .ne("genre", "");

            List<Artist> artists = artistMapper.selectList(queryWrapper);

            List<String> genres = artists.stream()
                    .filter(artist -> artist.getGenre() != null && !artist.getGenre().trim().isEmpty())
                    .flatMap(artist -> {
                        String[] genreArray = artist.getGenre().split("[,，]");
                        return java.util.Arrays.stream(genreArray)
                                .map(String::trim)
                                .filter(genre -> !genre.isEmpty());
                    })
                    .distinct()
                    .sorted()
                    .collect(Collectors.toList());

            // 在最前面添加"全部"选项
            List<String> result = new ArrayList<>();
            result.add("全部");
            result.addAll(genres);
            return result;
        } catch (Exception e) {
            log.error("获取歌手音乐风格失败", e);
            List<String> fallbackResult = new ArrayList<>();
            fallbackResult.add("全部");
            return fallbackResult;
        }
    }

    @Override
    public List<Artist> getArtistsByGenreMatch(String genre, Integer limit) {
        try {
            QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1);

            // 如果传入的是"全部"，则不添加音乐风格过滤条件
            if (!"全部".equals(genre)) {
                queryWrapper.and(wrapper -> wrapper.like("genre", genre));
            }

            queryWrapper.orderByDesc("create_time");

            if (limit != null && limit > 0) {
                queryWrapper.last("LIMIT " + limit);
            }

            return artistMapper.selectList(queryWrapper);
        } catch (Exception e) {
            log.error("根据音乐风格获取歌手失败", e);
            return Collections.emptyList();
        }
    }

    @Override
    public List<ArtistDetailDTO> getArtistsByGenreMatchWithDetails(String genre, Integer limit) {
        List<Artist> artists = getArtistsByGenreMatch(genre, limit);
        return artists.stream()
                .map(this::convertToArtistDetailDTO)
                .collect(Collectors.toList());
    }
}
